


import java.util.Arrays;
import java.util.HashSet;



public class NaiveSolutionFinder implements SolutionFinder 
{
	
//	private class MovePushCord
//	{
//		Cord lastPushCord;
//		Move move;
//		
//		private MovePushCord( Cord lastPusCord, Move move )
//		{
//			this.lastPushCord = lastPusCord;
//			this.move = move;
//		}
//	}
	
//	private class BoardWithPath
//	{
//		Board board;
//		String path;
//	}
	
	private int hash( Board board )
	{
		
		int pX = (byte) board.getPlayer().getX();
		int pY = (byte) board.getPlayer().getY();
		
//		int bX = (byte) board.getBoxes().get(0).getX();
//		int bY = (byte) board.getBoxes().get(0).getY();
		int bX = (byte) board.getBoxes()[0].getX();
		int bY = (byte) board.getBoxes()[0].getY();
		
		int hash = pX + ( pY * 256 ) + ( bX * (256*256) ) + ( bY * (256*256*256) );
		
		return hash;

	}
	
	private boolean finished = false;
	private String solution = "";
	VisitedCellHelper visited;
	NaiveMove naiveMoveRule = new NaiveMove();
	
	HashSet<Integer> visitedSet = new HashSet<Integer>();
	
	public void DFS( Board board, String path )
	{
		
		if ( finished )
		{
			return;
		}
		
		if ( visitedSet.contains( hash(board) ) )
		{
			return;
		}
		else
		{
			visitedSet.add( hash(board) );
		}
		
//		board.printBoard();
//		System.out.println("player: "+board.getPlayer());
		
//		if ( board.getBoxes().containsAll( board.getGoals() ) )
		if ( Arrays.equals( board.getBoxes() , board.getGoals()) )
		{
			System.out.println("alla boxar paa alla goals");
			finished = true;
			solution = path;
			return;
		}
		
		for ( Move move : board.getLegalMoves( board.getPlayer() , naiveMoveRule) )
		{
//			System.out.println("Move: "+ move.toString() );
			
//			if ( board.getCellType(move).isBox())
//			{
//				board.printBoard();
//			}
			
			Board newBoard = board.clone();
			
			newBoard.doMovePlayer( move.getDirectionToThis() );
			
			DFS( newBoard, path+move.getDirectionToThis().toString() );
		}
		
//		for ( Cord box : board.getBoxes() )
//		{
//			
//			for ( Move move : board.getLegalMoves(box, boxMoveRule) )
//			{
//				/*
//				 * Player maaste faorst gaa till move.doMove( move.getDirectionToThis().reverse )
//				 */
//				
//				Direction reverse = move.getDirectionToThis().reverse();
//				
//				Cord playerPosBeforeBoxMove = move.doNewMove(reverse).doNewMove(reverse);
//				
//				/*
//				 * Saok fraan board.getPlayer() till playerPosBeforeBoxMove
//				 */
//				
//				Board newBoard = board.clone();
//				
//				newBoard.doMovePlayer( move.getDirectionToThis() );
//				
//				DFS( newBoard );
//				
//			}
//			
//		}
	}
	
	/**
	 * Naive solution finder, expects a single goal and a single box.
	 */
	@Override
	public String FindSolution(Board board) 
	{
//		Cord goal = board.getGoals().get(0);
//		Cord box = board.getBoxes().get(0);
//		Cord player = board.getPlayer();
		
		/*
		 * Find a path from goal to box that reversely can move a box.
		 */
//		LinkedList<Move> findBoxQueue = new LinkedList<Move>();
//		findBoxQueue.add(new MoveImpl(box));
//		VisitedCellHelper visited = board.getVisitedBoardHelper();
//		
//		boxMoveRule = new BoxMove();
		
		board.printBoard();
//		
//		board.doMovePlayer(Direction.Down);
//		
//		board.printBoard();
//		
//		board.doMovePlayer(Direction.Down);
//		
//		board.printBoard();
		
		DFS(board, "");
		
//		System.out.println(solution);
		
		return solution;
		
//		while(true)
//		{
//
//			Move move = findBoxQueue.removeFirst(); // BFS
//			
////			System.out.println( move.getX() +":"+ move.getY() );
//			
//			if ( visited.unisitedCell(move) )
//			{
//				visited.registerCellAsVisited(move);
//				
//				/*
//				 * Hitta vaegen till det som flyttar hit.
//				 */
//				
//				
//				if ( board.getCellType(move) == CellType.BoxOnGoal )
//						{
//							return move.getPathToThis();
//						}
//						
//						for ( Move m : board.getLegalMoves(move, boxMoveRule) )
//						{
//							findBoxQueue.addLast( m );
//						}
//						
//				
//			}
//			else
//			{
//				// Do nothing
//			}
//		
//		}
		
	}

}
